use xevent::{Ime, Keyboard, Mouse, Touch, Wheel};

use crate as types;

#[derive(Debug)]
pub struct Application;
impl types::App for Application {
	type Error = EmptyError;
	type Ref<'a> = AppRef;
	fn with(_: impl FnOnce(Self::Ref<'_>)) {}
	fn run(_: impl crate::AppRep<Self>) -> Result<(), Self::Error> {
		Ok(())
	}
}
impl types::Log for Application {
	fn log(_: types::LevelFilter) {}
}
impl types::Fs for Application {
	fn read(_: impl AsRef<std::path::Path>) -> impl std::future::Future<Output = std::io::Result<Vec<u8>>> {
		std::future::ready(Err(std::io::Error::new(std::io::ErrorKind::Other, "not implemented")))
	}
}
#[derive(Clone, Copy)]
pub struct AppRef;
impl types::AppRef for AppRef {
	type Proxy = AppProxy;
	fn exit(&self) {}
	fn proxy(&self) -> AppProxy {
		AppProxy
	}
}
#[derive(Clone)]
pub struct AppProxy;
impl types::AppProxy for AppProxy {
	fn wake(&self, _: i64) {}
}

#[derive(Debug)]
pub struct Window;

impl types::Win for Window {
	type Error = EmptyError;
	type WinRaw = WinRaw;
	type WinRef<'a> = WinRef;
	type WinHandle = WinHandle;
	type Mouse<'a> = &'a Mouse;
	type Wheel<'a> = &'a Wheel;
	type Keyboard<'a> = &'a Keyboard;
	type Touch<'a> = &'a Touch;
	type Ime<'a> = &'a Ime;
	type Attr = types::XwinAttr;
	fn win(_key: impl AsRef<str>, _: Self::Attr, _: impl types::WinRep<Self> + 'static) -> Result<Self::WinHandle, Self::Error> {
		Err(EmptyError)
	}
}

#[derive(Debug)]
pub struct EmptyError;
impl std::fmt::Display for EmptyError {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		f.write_str("Error empty")
	}
}
impl std::error::Error for EmptyError {}

pub struct WinRaw;

pub struct WinHandle;
impl types::WinHandle<Window> for WinHandle {
	fn with(&self, _: impl FnOnce(WinRef)) {}
}

#[derive(Clone, Copy)]
pub struct WinRef;
impl types::WinRef<WinRaw> for WinRef {
	fn raw(&self) -> Option<WinRaw> {
		None
	}
	fn show(&self) {}
	fn close(&self) {}
	fn fresh(&self, _: &str) {}
	fn size(&self) -> (u32, u32) {
		(0, 0)
	}
	fn density(&self) -> f32 {
		1.0
	}
}
// pub struct AppHandle;
// impl types::AppHandle<Window> for AppHandle {
// 	fn singleton() -> Self {
// 		Self
// 	}
// 	fn with(&self, _: impl FnMut(<Window as types::Window>::AppRef<'_>)) {}
// }
